
//封装了线程与串口，一个线程对应一串口


#include "serialthread.h"
#include <QDebug>

using namespace Moolink;

MasterThread::MasterThread(QObject *parent) :
    QThread(parent)
{
}

//! [0]
MasterThread::~MasterThread()
{
    m_mutex.lock();
    m_quit = true;
    m_cond.wakeOne();
    m_mutex.unlock();
    wait();
}
//! [0]

//! [1] //! [2]
void MasterThread::transaction(const int devIndex,const QString &devName,const QString &portName,const QSerialPort::BaudRate baudrate, QSerialPort::DataBits databits, QSerialPort::Parity parity, QSerialPort::StopBits stopbits, int waitTimeout, const QByteArray &request)
{
//! [1]
    const QMutexLocker locker(&m_mutex);
    m_devIndex=devIndex;
    m_devName=devName;
    m_portName = portName;
    m_baudrate=baudrate;
    m_databits=databits;
    m_parity=parity;
    m_stopbits=stopbits;

    m_waitTimeout = waitTimeout;
    m_request = request;
//! [3]
    if (!isRunning())
        start();
    else
        m_cond.wakeOne();
}
//! [2] //! [3]

//! [4]
void MasterThread::run()
{
    bool currentPortNameChanged = false;

    m_mutex.lock();
//! [4] //! [5]
    QString currentPortName;
    if (currentPortName != m_portName) {
        currentPortName = m_portName;
        currentPortNameChanged = true;
    }

    int currentWaitTimeout = m_waitTimeout;
    QByteArray currentRequest = m_request;
    m_mutex.unlock();
//! [5] //! [6]
    QSerialPort serial;

    if (currentPortName.isEmpty()) {
        emit error(m_devIndex,m_devName,"E00:No port name specified");
        return;
    }
    //qDebug()<<"MasterThread::run()--\r\n";
    while (!m_quit) {
//![6] //! [7]
//        if (currentPortNameChanged) {
//            serial.close();
       //qDebug()<<"MasterThread:"<<currentRequest<<"\r\n";
            serial.setPortName(currentPortName);

            if (serial.open(QIODevice::ReadWrite))
            {
                serial.setBaudRate(m_baudrate);//QSerialPort::Baud9600);

                serial.setDataBits(m_databits);//QSerialPort::Data8);          //设置数据位8

                serial.setParity(m_parity);//QSerialPort::NoParity);         //校验位设置为0

                serial.setStopBits(m_stopbits);//QSerialPort::OneStop);        //停止位设置为1

                serial.setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制

            }
            else
            {
                emit error(m_devIndex,m_devName,"E01:Can't open "+m_portName);
//                           .arg(m_portName).arg(serial.error()));
                return;
            }



//        }
//! [7] //! [8]
//!
        // write request
        //const QByteArray requestData = currentRequest.toLatin1();
        //serial.readAll();
        serial.write(currentRequest);
        if (serial.waitForBytesWritten(m_waitTimeout)) {
//! [8] //! [10]
            // read response
            if (serial.waitForReadyRead(currentWaitTimeout)) {
                QByteArray responseData = serial.readAll();
                while (serial.waitForReadyRead(50))
                    responseData += serial.readAll();

                //const QString response = QString::fromLatin1(responseData);
//! [12]
                emit this->response2(m_devIndex,m_devName,responseData);
//! [10] //! [11] //! [12]
            } else {
                emit error(m_devIndex,m_devName,"E02:Wait read response timeout");
//                             .arg(QTime::currentTime().toString()));
            }
//! [9] //! [11]
        } else {
            emit error(m_devIndex,m_devName,"E03:Wait write request timeout");
 //                        .arg(QTime::currentTime().toString()));
        }
//! [9]  //! [13]
//!     
//!
        serial.close();
        m_mutex.lock();
        m_cond.wait(&m_mutex);
        if (currentPortName != m_portName) {
            currentPortName = m_portName;
            currentPortNameChanged = true;
        } else {
            currentPortNameChanged = false;
        }
        currentWaitTimeout = m_waitTimeout;
        currentRequest = m_request;
        m_mutex.unlock();
    }
//! [13]
}
